package com.lyl.activiti.demo.web.controller;

import com.lyl.activiti.demo.bean.Leave;
import com.lyl.activiti.demo.bpm.cmd.HistoryProcessInstanceDiagramCmd;
import com.lyl.activiti.demo.bpm.cmd.WithdrawTaskCmd;
import com.lyl.activiti.demo.mapper.CustomMapper;
import com.lyl.activiti.demo.mapper.LeaveMapper;
import org.activiti.engine.history.HistoricProcessInstance;
import org.activiti.engine.history.HistoricTaskInstance;
import org.activiti.engine.identity.User;
import org.activiti.engine.impl.interceptor.Command;
import org.activiti.engine.repository.ProcessDefinition;
import org.activiti.engine.repository.ProcessDefinitionQuery;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.runtime.ProcessInstanceQuery;
import org.activiti.engine.task.Task;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.InputStream;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Created by liyulong on 14-4-21.
 */

@Controller
@RequestMapping(value = "/taskCustomForm")
public class TaskCustomFormController extends BaseController {

    @Autowired
    LeaveMapper leaveMapper;
    @Autowired
    CustomMapper customMapper;

    private static final String CUSTOM_FORM_PROCESS_DEFINITION_KEY = "leaveCustomFormProcess";

    /**
     * 流程列表
     *
     * @param model
     * @return
     */
    @RequestMapping(value = "/processList")
    public String processList(Model model) {
        ProcessDefinitionQuery processDefinitionQuery = repositoryService.createProcessDefinitionQuery();
        //获取最新版本的流程定义
        List<ProcessDefinition> processDefinitionList = processDefinitionQuery.latestVersion().processDefinitionKey(CUSTOM_FORM_PROCESS_DEFINITION_KEY).orderByProcessDefinitionId().asc().list();

        model.addAttribute("processList", processDefinitionList);
        return "/taskCustomForm/processList";
    }

    /**
     * 开始流程
     * @param leave
     * @param session
     * @return
     */
    @RequestMapping(value = "/startProcess")
    public String startProcess(Leave leave, HttpSession session) {
        String userId = ((User) session.getAttribute("user")).getId();
        leave.setApplyUserId(userId);
        //存储表单信息
        leaveMapper.insert(leave);
        // 启动用户信息
        identityService.setAuthenticatedUserId(userId);
        ProcessInstance processInstance = runtimeService.startProcessInstanceByKey(CUSTOM_FORM_PROCESS_DEFINITION_KEY, String.valueOf(leave.getId()));
        return "redirect:/taskCustomForm/processList";
    }

    /**
     * 获取当前任务的表单
     *
     * @param taskDefinitionKey
     * @return
     * @throws Exception
     */
    @RequestMapping(value = "/getTaskForm/{taskDefinitionKey}/{taskId}/{processInstanceId}")
    public String getTaskForm(@PathVariable("taskDefinitionKey") String taskDefinitionKey, @PathVariable("taskId") String taskId, @PathVariable("processInstanceId") String processInstanceId, Model model) throws Exception {
        ProcessInstance processInstance = runtimeService.createProcessInstanceQuery().processInstanceId(processInstanceId).singleResult();
        Leave leave = leaveMapper.selectByPrimaryKey(Integer.valueOf(processInstance.getBusinessKey()));
        model.addAttribute("leave",leave);
        model.addAttribute("taskId",taskId);
        if("managerApprove".equals(taskDefinitionKey)){
            return "/taskCustomForm/managerApprove";
        }else if ("modifyApply".equals(taskDefinitionKey)){
            return "/taskCustomForm/modifyApply";
        }else if ("reportBack".equals(taskDefinitionKey)){
            return "/taskCustomForm/reportBack";
        }
        return "";
    }
    @RequestMapping(value = "/getFinishedTaskForm/{businessKey}")
    public String getFinishedTaskForm(@PathVariable("businessKey") int businessKey, Model model){
        Leave leave = leaveMapper.selectByPrimaryKey(businessKey);
        model.addAttribute("leave", leave);
        return "/taskCustomForm/finishedTaskForm";
    }


    /**
     * 完成经理审批
     * @param leave
     * @param deptLeaderPass
     * @param taskId
     * @param session
     * @return
     */
    @RequestMapping(value = "/completeTaskManagerApprove")
    @ResponseBody
    public String completeTaskManagerApprove(Leave leave,@RequestParam("deptLeaderPass") String deptLeaderPass,  @RequestParam("taskId") String taskId, HttpSession session) {
        String userId = ((User) session.getAttribute("user")).getId();
        //更新leave表
        leaveMapper.updateByPrimaryKeySelective(leave);

        Map<String, String> formProperties = new HashMap<String, String>();
        formProperties.put("deptLeaderPass",deptLeaderPass);
        try {
            identityService.setAuthenticatedUserId(userId);
            formService.submitTaskFormData(taskId, formProperties);
        } finally {
            identityService.setAuthenticatedUserId(null);
        }
        return "true";
    }

    /**
     * 完成修改申请
     * @param leave
     * @param reApply
     * @param taskId
     * @param session
     * @return
     */
    @RequestMapping(value = "/completeTaskModifyApply")
    public String completeTaskModifyApply(Leave leave,@RequestParam("reApply") String reApply,  @RequestParam("taskId") String taskId, HttpSession session) {
        String userId = ((User) session.getAttribute("user")).getId();
        //更新leave表
        leaveMapper.updateByPrimaryKeySelective(leave);

        Map<String, String> formProperties = new HashMap<String, String>();
        formProperties.put("reApply",reApply);
        try {
            identityService.setAuthenticatedUserId(userId);
            formService.submitTaskFormData(taskId, formProperties);
        } finally {
            identityService.setAuthenticatedUserId(null);
        }
        return "/taskCustomForm/processList";
    }

    /**
     * 销假
     * @param taskId
     * @param session
     * @return
     */
    @RequestMapping(value = "/completeTaskReportBack")
    public String completeTaskReportBack(@RequestParam("taskId") String taskId, HttpSession session) {
        String userId = ((User) session.getAttribute("user")).getId();
        try {
            identityService.setAuthenticatedUserId(userId);
            taskService.complete(taskId);
        } finally {
            identityService.setAuthenticatedUserId(null);
        }
        return "/taskCustomForm/processList";
    }

    /**
     * 待办任务列表
     *
     * @param model
     * @param session
     * @return
     */
    @RequestMapping(value = "/toDoProcessList")
    public String userToDoProcessList(Model model, HttpSession session) {
        String userId = ((User) session.getAttribute("user")).getId();
        //获取当前用户为候选人的任务
        List<Task> tasks = taskService.createTaskQuery().processDefinitionKey(CUSTOM_FORM_PROCESS_DEFINITION_KEY).taskCandidateUser(userId).list();
        //获取已经分配给当前用户的任务
        List<Task> tasks1 = taskService.createTaskQuery().processDefinitionKey(CUSTOM_FORM_PROCESS_DEFINITION_KEY).taskAssignee(userId).list();
        tasks.addAll(tasks1);
        model.addAttribute("tasks", tasks);

        //根据待办中的processInstanceId获得ProcessInstance ProcessDefinition
        HashMap<String,HistoricProcessInstance> historicProcessInstances = new HashMap<String, HistoricProcessInstance>();
        HashMap<String,ProcessDefinition> processDefinitions = new HashMap<String, ProcessDefinition>();
        for (Task task : tasks) {
            HistoricProcessInstance historicProcessInstance = historyService.createHistoricProcessInstanceQuery().processInstanceId(task.getProcessInstanceId()).singleResult();
            historicProcessInstances.put(task.getProcessInstanceId(),historicProcessInstance);

            ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery().processDefinitionId(task.getProcessDefinitionId()).singleResult();
            processDefinitions.put(task.getProcessDefinitionId(),processDefinition);
        }
        model.addAttribute("historicProcessInstances",historicProcessInstances);
        model.addAttribute("processDefinitions",processDefinitions);


        return "/taskCustomForm/toDoProcessList";
    }

    /**
     * 签收流程
     *
     * @param taskId
     * @param session
     * @return
     */
    @RequestMapping(value = "/claimProcess")
    public String claimProcess(String taskId, HttpSession session) {
        String userId = ((User) session.getAttribute("user")).getId();
        taskService.claim(taskId, userId);
        return "redirect:/taskCustomForm/toDoProcessList";
    }

    /**
     * 运行中流程
     *
     * @param model
     * @return
     */
    @RequestMapping(value = "/runningProcessList")
    public String runningProcess(Model model, HttpSession session) {
        String userId = ((User) session.getAttribute("user")).getId();
        List<ProcessInstance> runningProcessList = runtimeService.createProcessInstanceQuery().processDefinitionKey(CUSTOM_FORM_PROCESS_DEFINITION_KEY).involvedUser(userId).active().list();
        model.addAttribute("runningProcessList", runningProcessList);

        //根据processDefinitionId获得 ProcessDefinition
        HashMap<String,ProcessDefinition> processDefinitions = new HashMap<String, ProcessDefinition>();
        for (ProcessInstance processInstance : runningProcessList) {
            ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery().processDefinitionId(processInstance.getProcessDefinitionId()).singleResult();
            processDefinitions.put(processInstance.getProcessDefinitionId(),processDefinition);
        }
        model.addAttribute("processDefinitions",processDefinitions);
        return "/taskCustomForm/runningProcessList";
    }

    /**
     * 显示流程的详细历史
     * @param processInstanceId
     * @param model
     * @param session
     * @return
     */
    @RequestMapping(value = "/runningProcessHistory/{processInstanceId}")
    public String runningProcessHistory(@PathVariable("processInstanceId") String processInstanceId, Model model, HttpSession session) {
        String userId = ((User) session.getAttribute("user")).getId();

        List<HistoricTaskInstance> historicTasks = historyService
                .createHistoricTaskInstanceQuery()
                .processInstanceId(processInstanceId).list();
        model.addAttribute("historicTasks",historicTasks);

        return "/taskCustomForm/processHistory";
    }

    /**
     * 已完成的流程实例
     *
     * @param model
     * @return
     */
    @RequestMapping(value = "/finishedProcessList")
    public String finished(Model model, HttpServletRequest request, HttpSession session) {
        String userId = ((User) session.getAttribute("user")).getId();
        List<HistoricProcessInstance> finishedProcessList = historyService.createHistoricProcessInstanceQuery().processDefinitionKey(CUSTOM_FORM_PROCESS_DEFINITION_KEY).startedBy(userId).orderByProcessInstanceEndTime().desc().finished().list();
        model.addAttribute("finishedProcessList", finishedProcessList);

        //根据processDefinitionId获得 ProcessDefinition
        HashMap<String,ProcessDefinition> processDefinitions = new HashMap<String, ProcessDefinition>();
        for (HistoricProcessInstance historicProcessInstance : finishedProcessList) {
            ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery().processDefinitionId(historicProcessInstance.getProcessDefinitionId()).singleResult();
            processDefinitions.put(historicProcessInstance.getProcessDefinitionId(),processDefinition);
        }
        model.addAttribute("processDefinitions", processDefinitions);
        return "/taskCustomForm/finishedProcessList";
    }

    /**
     * 获取当前流程实例的流程图
     * @param processInstanceId
     * @param response
     * @throws Exception
     */
    @RequestMapping(value = "/image/{processInstanceId}")
    public void getImage(@PathVariable("processInstanceId") String processInstanceId, HttpServletResponse response) throws Exception {
        Command<InputStream> cmd = new HistoryProcessInstanceDiagramCmd(processInstanceId);

        InputStream is = managementService.executeCommand(cmd);
        response.setContentType("image/png");

        int len = 0;
        byte[] b = new byte[1024];

        while ((len = is.read(b, 0, 1024)) != -1) {
            response.getOutputStream().write(b, 0, len);
        }
    }

    /**
     * 获取流程定义图
     *
     * @param processDefinitionId
     * @param response
     * @throws Exception
     */
    @RequestMapping(value = "/processDefinitionImage/{processDefinitionId}")
    public void getProcessDefinitionImage(@PathVariable("processDefinitionId") String processDefinitionId, HttpServletResponse response) throws Exception {
        ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery().processDefinitionId(processDefinitionId).singleResult();
        InputStream resourceAsStream = repositoryService.getResourceAsStream(processDefinition.getDeploymentId(), processDefinition.getDiagramResourceName());
        byte[] b = new byte[1024];
        int len = -1;
        while ((len = resourceAsStream.read(b, 0, 1024)) != -1) {
            response.getOutputStream().write(b, 0, len);
        }
    }

    /**
     * 已办任务
     * @param model
     * @param session
     * @return
     */
    @RequestMapping(value = "/processedTaskList")
    public String processedTaskList(Model model, HttpSession session) {
        String userId = ((User) session.getAttribute("user")).getId();
        List<HistoricTaskInstance> processedTasks = historyService
            .createHistoricTaskInstanceQuery().taskAssignee(userId)
            .finished().list();
        model.addAttribute("processedTasks", processedTasks);
        //根据processInstanceId获得processInstace
        HashMap<String,HistoricProcessInstance> processInstances = new HashMap<String, HistoricProcessInstance>();
        for (HistoricTaskInstance processedTask : processedTasks) {
            HistoricProcessInstance historicProcessInstance = historyService.createHistoricProcessInstanceQuery().processInstanceId(processedTask.getProcessInstanceId()).singleResult();
            processInstances.put(processedTask.getProcessInstanceId() ,historicProcessInstance);
        }
        model.addAttribute("processInstances",processInstances);
        return "/taskCustomForm/processedTaskList";
    }

    /**
     * 撤销已办任务
     * @param taskId
     * @return
     */
    @RequestMapping(value = "/callBack/{taskId}")
    @ResponseBody
    public String callBack(@PathVariable("taskId") String taskId){
        Command<Integer> cmd = new WithdrawTaskCmd(taskId);
        return managementService.executeCommand(cmd).toString();
    }

}
